from fastapi import HTTPException, status
from sqlalchemy import Result, select
from sqlalchemy.ext.asyncio import AsyncSession

from scaner.core.models import User
from scaner.core.config.log_config import MyLogger
from . import schemas
from . import utils as auth_utils

main_logger = MyLogger()
logger = main_logger.getChild("auth")  # type: ignore


async def get_user_by_names(session: AsyncSession, username: str) -> User | None:
    logger.info("get_user_by_names")  # type: ignore
    stmt = select(User).where(User.username == username)
    result: Result = await session.execute(stmt)
    user: User | None = result.scalar_one_or_none()
    return user


async def get_user_by_email(session: AsyncSession, email: str) -> User | None:
    logger.info("get_user_by_email")  # type: ignore
    stmt = select(User).where(User.email == email)
    result: Result = await session.execute(stmt)
    user: User | None = result.scalar_one_or_none()
    return user


async def get_user_by_id(session: AsyncSession, user_id: int) -> User | None:
    logger.info("get_user_by_id")  # type: ignore
    return await session.get(User, user_id)


async def sign_up_user(
    session: AsyncSession, user_data: schemas.UserCreate
) -> User | None:
    logger.info("sign_up_user")  # type: ignore

    stmt = select(User).where(User.email == user_data.email)
    result: Result = await session.execute(stmt)
    user: User | None = result.scalar_one_or_none()

    if user:
        error_text = f"Пользователь с почтой {user_data.email} существует"
        logger.error(error_text)  # type: ignore
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=error_text,
        )

    user_dict = user_data.model_dump()
    del user_dict["password"]

    user = User(**user_dict)
    user.hashed_password = auth_utils.hash_password(user_data.password)

    session.add(user)
    await session.commit()
    await session.refresh(user)

    return user
